﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace demo
{
    public partial class FrmCreateTool : Form
    {
        public List<Type> TypeList { get;  set; }
        public List<MethodInfo> FunList { get;  set; }
        public List<string> ParaTypes { get; set; } = new List<string>();
        public List<string> ParaNames { get;  set; } = new List<string>();
        public ActionItem _customTool { get; set; } = new ActionItem();
        public ConstructorInfo[] _constructorInfos;
        public FrmCreateTool()
        {
            InitializeComponent();
        }

        private void FrmCreateTool_Load(object sender, EventArgs e)
        {
            RefreshDllAndIcon();

            var groups = ToolMgr.Ins.Tools.Select(tool => tool.Group).ToList().Distinct().ToList();
            groups.ForEach(group => comboBox1.Items.Add(group));
        }

        private void RefreshDllAndIcon()
        {
            string[] files = Directory.GetFiles(Environment.CurrentDirectory, "*.dll");
            listBox4.Items.Clear();
            listBox5.Items.Clear();
            foreach (var file in files)
            {
                try
                {
                    if (ReflectAble.GetTypes(file).Count > 0)
                    {
                        listBox4.Items.Add(Path.GetFileName(file));
                        listBox5.Items.Add(Path.GetFileName(file));
                        
                    }
                }
                catch (Exception exception)
                {
                    
                }
            }

            
        }

       
        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listBox5.SelectedIndex!=-1)
            {
                _constructorInfos = (listBox2.SelectedItem as Type).GetConstructors();
                BindingSource bs = new BindingSource();
                bs.DataSource = _constructorInfos;
                listBox3.DataSource = bs;
            }
            if (listBox4.SelectedIndex!=-1)
            {
                FunList = ReflectAble.GetMethod(listBox2.SelectedItem as Type);
                BindingSource bs = new BindingSource();
                bs.DataSource = FunList;
                listBox3.DataSource = bs;
                listBox3.DisplayMember = "signature";
            }

            
        }

        private void listBox3_SelectedIndexChanged(object sender, EventArgs e)
        {
            ParameterInfo[] methodParams=null;
            if (listBox5.SelectedIndex==-1)
            {
                 methodParams = (listBox3.SelectedItem as MethodInfo)?.GetParameters();
            }
            if (listBox4.SelectedIndex==-1)
            {
                 methodParams = (listBox3.SelectedItem as ConstructorInfo)?.GetParameters();
            }
            ParaTypes.Clear();
            ParaNames.Clear();
            if (methodParams != null)
                foreach (var parameter in methodParams)
                {
                    ParaTypes.Add(parameter.ParameterType.FullName);
                    ParaNames.Add(parameter.Name);
                }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshDllAndIcon();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            foreach (var tool in ToolMgr.Ins.Tools)
            {
                if (tool.ItemName == textBox1.Text)
                {
                    MessageBox.Show($"工具名{textBox1.Text}已存在，请重新输入");
                    return;
                }
            }
            Type tp = listBox2.SelectedItem as Type;
            if (typeof(ActionItem).IsAssignableFrom(tp))
            {
                if (tp?.FullName != typeof(ActionItem).FullName)
                {
                    _customTool = (ActionItem)Activator.CreateInstance(tp);
                }
            }
            if (listBox5.SelectedIndex == -1) 
            {
                _customTool.Dll = listBox4.SelectedItem.ToString();
                _customTool.MethodName = (listBox3.SelectedItem as MethodInfo)?.Name;
                _customTool.IsStatic = ((MethodInfo)listBox3.SelectedItem).IsStatic;
                _customTool.ReturnType = (listBox3.SelectedItem as MethodInfo)?.ReturnType.FullName;
            }
            if (listBox4.SelectedIndex==-1)
            {
                _customTool.Dll = listBox5.SelectedItem.ToString();
                
                var ci = listBox3.SelectedItem as ConstructorInfo;
                _customTool.MethodName = (ci)?.Name;
                _customTool.IsStatic = true;
                _customTool.Parms.Clear();

                _customTool.ReturnType = typeof(object).FullName;
                _customTool.IsConstructor = true;
            }
            _customTool.ItemName = textBox1.Text;            
            _customTool.TypeName = (listBox2.SelectedItem as Type)?.FullName;          
            _customTool.Group = comboBox1.Text;
            _customTool.ParaTypes.Clear();
            _customTool.ParaNames.Clear();            
            ParaTypes.ForEach(item => _customTool.ParaTypes.Add(item));
            ParaNames.ForEach(item => _customTool.ParaNames.Add(item));
            ToolMgr.Ins.Tools.Add(_customTool);
            ToolMgr.Ins.SaveTool(_customTool);
            DialogResult = DialogResult.OK;
            Close();
        }

        private void listBox4_SelectedIndexChanged(object sender, EventArgs e)
        {
            int a = listBox4.SelectedIndex;
            listBox5.SelectedIndex = -1;
            listBox4.SelectedIndex=a;
            if (listBox4.SelectedItem == null)
            {
                return;
            }
            string fileName = Environment.CurrentDirectory + "\\" + listBox4.SelectedItem;
            TypeList = ReflectAble.GetTypes(fileName);
            BindingSource bs = new BindingSource();
            bs.DataSource = TypeList;
            listBox2.DataSource = bs;
            listBox2.DisplayMember = "Name";
        }

        private void listBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            int a = listBox5.SelectedIndex;
            listBox4.SelectedIndex = -1;
            listBox5.SelectedIndex = a;
            if (listBox5.SelectedItem == null)
            {
                return;
            }
            string fileName = Environment.CurrentDirectory + "\\" + listBox5.SelectedItem;
            TypeList = ReflectAble.GetTypes(fileName);
            BindingSource bs = new BindingSource();
            bs.DataSource = TypeList;
            listBox2.DataSource = bs;
            listBox2.DisplayMember = "Name";
        }

       
    }
}
